home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************************
-
-
- MassDecode
-
-
- Copyright ©1994 by Gregg Giles
-
- BETA CODE - DO NOT REDISTRIBUTE - BETA CODE - DO NOT REDISTRIBUTE
-
-
- ***************************************************************************/
-
-
- /***************************************************************************
- GET COMMAND LINE ARGUMENTS
- ***************************************************************************/
-
- parse arg arguments
-
-
-
- /***************************************************************************
- DEFINITIONS
- Warning: be sure to check the scope!
- ***************************************************************************/
-
- /* Default decoder */
- UUDECODER = 'SmartDecode' /* default decoder path */
-
- /* Newsgroup name */
- NEWSGROUP = 'alt.binaries.pictures.erotica' /*** NOT IMPLEMENTED ***/
-
- /* MassDecode log file directory */
- LOGS = 'md:MassDecode/logs/' /*** NOT IMPLEMENTED ***/
-
- /* Progam definitions */
- PROG_AUTHOR = 'Gregg Giles' /* author */
- PROG_COPYRIGHT = '1994' /* Copyright */
- PROG_DATE = '11 March 1994' /* release date */
- PROG_NAME = 'MassDecode' /* program name */
- PROG_VERSION = '1.00 Beta-4' /* program version */
-
- /* global definitions */
- OFF = 0 /* test condition */
- ON = 1 /* test condition */
- NO = 0 /* test condition */
- YES = 1 /* test condition */
- TEMP_DATE = ' ' /* date */
- TEMP_TIME = ' ' /* time */
- QUIET = OFF /* controls console output */
-
- /* counters */
- ctr_HeaderLine = 0 /* counter: tracks current line # of message header */
-
- /* file's message header structure */
- HEADER. = 0 /* structure for file's message header */
- HEADER.LINES = 0 /* number of lines in header */
- HEADER.SEARCH_MAX = 50 /* number of lines after which to stop looking for header data */
-
- /* message file information structure */
- UUFILE. = 0
- UUFILE.INNAME = '<inname>' /* name of input file (no path) */
- UUFILE.INPATH = '<inpath>' /* path to input file (no name) */
- UUFILE.INPATHNAME = '<inpathname>' /* path and filename of input file */
- UUFILE.OUTNAME = '<outname>' /* name of output file (no path) */
- UUFILE.OUTPATH = '<outpath>' /* path to output file (no name) */
- UUFILE.OUTPATHNAME= '<outpathname>' /* path and filename of output file */
- UUFILE.PARTNUM = 0 /* part number of file's message */
- UUFILE.PARTSTOTAL = 0 /* total parts to file's message */
- UUFILE.SUBJECT = '<subject>' /* subject of file's message */
- UUFILE.UUENCODER = '<uuencoder>' /* uuencoder used to create file's message */
- UUFILE.VALID = NO /* tells if file contains valid uuencoded msg */
-
- /* Totals */
- TOTALS. = 0 /* totals information structure */
- TOTALS.VALID = 0 /* number of valid uudecoded messages found */
- TOTALS.MSGS = 0 /* number of messages examined */
- TOTALS.DECODED = 0 /* number binaries created */
-
-
-
- /***************************************************************************
- CONSOLE OUTPUT
- If told to do so, turn off console I/O completely
- ***************************************************************************/
-
- if (find(upper(arguments), 'QUIET')>0) then do
- QUIET = ON
- end
-
-
-
- /***************************************************************************
- DISPLAY PROGRAM INFORMATION
- ***************************************************************************/
-
- if (QUIET = OFF) then do
- say PROG_NAME 'Version' PROG_VERSION '('PROG_DATE')'
- say 'Copyright ©'PROG_COPYRIGHT 'by' PROG_AUTHOR
- say ''
- end
-
-
- /***************************************************************************
- DISPLAY USAGE TEMPLATE IF NO ARGUMENTS ARE GIVEN
- ***************************************************************************/
-
- if (words(arguments)=0) then do
- say 'Usage: rx MassDecode SOURCE <source_dir> DEST <dest_dir>'
- say ' [DECODER <path/name>] [HEADERLINES <max_lines>]'
- say ' [DEBUG=<level>] [QUIET]'
- end
-
-
-
- /***************************************************************************
- DEBUGGING LEVEL
- Higher levels increase verbosity
- ***************************************************************************/
-
- DEBUG = 0 /* default debugging value */
- LOC_DEBUG = pos('DEBUG=', upper(arguments))
-
- if (LOC_DEBUG > 0) then do
- DEBUG = substr(arguments, LOC_DEBUG+length('DEBUG='), 1)
- if ((DEBUG<0)|(DEBUG>9)) then do
- say 'Error: Invalid DEBUG value - not displaying debug information'
- end
- end
-
-
-
- /***************************************************************************
- GET SOURCE DIRECTORY FROM PARAMETERS
- ***************************************************************************/
-
- POS_SOURCE = find(upper(arguments), 'SOURCE')
-
- /* If no source directory was supplied, show error message, then exit */
- if (POS_SOURCE=0) then do
- say 'Error: no source directory specified'
- exit /* exit program */
- end
-
- SOURCE_DIR = word(arguments, POS_SOURCE+1) /* get source from arguments */
-
- /* Ensure source dir has colon or slash on end, otherwise program will fail */
- TMP_CHAR = right(SOURCE_DIR, 1)
- if ((TMP_CHAR ~= '/')&(TMP_CHAR ~= ':')) then do
- if (DEBUG >= 5) then do
- say '*** Forcing slash onto end of source directory path'
- end
- SOURCE_DIR = SOURCE_DIR'/' /* force slash onto end */
- end
-
-
-
- /***************************************************************************
- GET DESTINATION DIRECTORY FROM PARAMETERS
- ***************************************************************************/
-
- POS_DEST = find(upper(arguments), 'DEST')
-
- /* If no destination directory was supplied, show error message, then exit */
- if (POS_DEST=0) then do
- say 'Error: no destination directory specified'
- exit /* exit program */
- end
-
- DEST_DIR = word(arguments, POS_DEST+1) /* get destination from arguments */
-
- /* Ensure dest dir has colon or slash on end, otherwise program will fail */
- TMP_CHAR = right(DEST_DIR, 1)
- if ((TMP_CHAR ~= '/')&(TMP_CHAR ~= ':')) then do
- if (DEBUG >= 5) then do
- say '*** Forcing slash onto end of destination directory path'
- end
- DEST_DIR = DEST_DIR'/' /* force slash onto end */
- end
-
-
-
- /***************************************************************************
- GET HEADERLINES VALUE FROM PARAMATERS
- The "HEADERLINES" variable specifies how many lines of the input file can
- be looked through before the search for header data is aborted. Normally,
- this value isn't needed when uuencoded data is found; however, it is
- provided as a safety feature to prevent slowdowns caused by searching an
- entire input file which has no uuencoded data.
- **************************************************************************/
-
- POS_HEADERLINES = find(upper(arguments), 'HEADERLINES')
-
- if (POS_HEADERLINES > 0) then do
- HEADER.SEARCH_MAX = word(arguments, POS_HEADERLINES+1)
- if (DEBUG >= 5) then do
- say '*** HEADER.SEARCH_MAX='HEADER.SEARCH_MAX
- end
- end
-
-
-
- /***************************************************************************
- GET DECODER FROM PARAMETERS
- If an alternate decoder is specified, check to make sure it exists, and if
- it does, use it.
- ***************************************************************************/
-
- POS_UUDECODER = find(upper(arguments), 'DECODER')
-
- if (POS_UUDECODER > 0) then do
- WORD_UUDECODER = word(arguments, POS_UUDECODER+1)
- if (exists(WORD_UUDECODER)>0) then do
- UUDECODER = WORD_UUDECODER
- if (DEBUG >= 5) then do
- say '*** UUDECODER='UUDECODER
- end
- end
- end
-
-
-
- /***************************************************************************
- Open rexxsupport.library if not already open
- ***************************************************************************/
-
- /* Open rexxsupport.library if not open */
- if ~show('L', 'rexxsupport.library') then do
- if addlib('rexxsupport.library', 0, -30, 0) then do
- if (DEBUG >= 6) then do
- say 'Added rexxsupport.library'
- end
- end
- else do
- say 'Error: cannot open rexxsupport.library'
- exit 10
- end
- end
-
-
- /***************************************************************************
- GET SOURCE_DIR INFORMATION
- ***************************************************************************/
-
- if (QUIET = OFF) then do
- say 'Phase: Scanning source directory'
- say ''
- end
-
- /* If source directory doesn't exist, issue error message and exit */
- if (exists(SOURCE_DIR)=0) then do
- say 'Error: source directory doesn''t exist ("'SOURCE_DIR'")'
- exit /* exit program*/
- end
-
- /* get filenames from directory and stuff them into a string */
- if (DEBUG >= 1) then do
- say 'Processing:' SOURCE_DIR
- end
- DIR_CONTENTS = showdir(SOURCE_DIR, 'f')
-
- /* get the total number of files in specified directory */
- NUM_FILES = words(DIR_CONTENTS)
- TOTALS.MSGS = NUM_FILES
- if (DEBUG >= 5) then do
- say '*** NUM_FILES='NUM_FILES
- end
-
-
- /***************************************************************************
- GENERATE TEMPORARY DATAFILE NAME
- This data file is used to store information for the decode phase
- ***************************************************************************/
-
- TEMP_DATE = space(date(julian), 0)
- TEMP_TIME = space(time(seconds), 0)
- TEMPDATAFILENAME = 'MD_'TEMP_DATE''TEMP_TIME'.TMP'
- if (DEBUG >= 1) then do
- say 'Datafile:' TEMPDATAFILENAME
- end
-
- /* Create the data file */
- result = open('TEMPDATA', TEMPDATAFILENAME, write)
- result = close('TEMPDATA')
-
- /***************************************************************************
- INTERPRET FILES
- ***************************************************************************/
-
- /* display message that file interpretation has begun */
- if (QUIET = OFF) then do
- say 'Phase: Recognition'
- say ''
- end
-
- /* Process each file until all have been interpreted */
- do ctr=1 to NUM_FILES
- if (QUIET = OFF) then do
- say 'Checking file' ctr 'of' NUM_FILES
- end
-
- /* Reset defaults */
- UUFILE.INNAME = word(DIR_CONTENTS, ctr) /* get name of input file (without path) */
- UUFILE.INPATH = SOURCE_DIR /* get path to input file */
- UUFILE.INPATHNAME = UUFILE.INPATH''UUFILE.INNAME /* make input file pathname */
- UUFILE.OUTNAME = '<reset>' /* output file name */
- UUFILE.OUTPATH = '<reset>' /* output path */
- UUFILE.OUTPATHNAME= '<reset>' /* output pathname */
- UUFILE.PARTNUM = 0 /* file's message part number */
- UUFILE.PARTSTOTAL = 0 /* total parts to message */
- UUFILE.SUBJECT = '<reset>' /* input file's subject */
- UUFILE.UUENCODER = '<reset>' /* file's message uuencoder */
- UUFILE.VALID = NO /* valid uuencoded msg in file? */
-
-
- /************************************************************************
- OPEN FILE FOR READING
- ************************************************************************/
-
- if (DEBUG >= 5) then do
- say '*** UUFILE.INPATHNAME='UUFILE.INPATHNAME
- end
- result = open('datafile', UUFILE.INPATHNAME, read)
-
-
- /************************************************************************
- READ IN MESSAGE HEADER FROM FILE
- By reading in the header of the message, it should be possible to
- determine everything needed to uudecode the file properly, including the
- name, and part number if the uuencoded binary is spread across multiple
- messages.
- ************************************************************************/
-
- /* Initialize the array used to store the file's mesage header */
- /***HEADER. = 0***/
-
- /* Reset flag which determines if reading from file should be stopped */
- STOP = NO /* reset loop control flag */
- ctr_HeaderLine = 1 /* reset header line counter */
- MCOUNTER = 0 /* safety counter: counts uuencode data line */
- PERCENT = 0 /* percentage of messages examined that are uuencoded */
-
- /* Read from file until the actual uuencoded data is reached (or EOF) */
- do until (STOP=YES)
- instring = readln('datafile') /* read line from file */
-
- HEADER.ctr_HeaderLine = instring /* copy line into header structure */
- if (DEBUG >= 9) then do
- say ctr_HeaderLine' 'HEADER.ctr_HeaderLine
- end
-
- /* Count lines which begin with "M" - data lines in uuencoded messages
- begin with "M"; this is a safety in case messages such as parts do
- not have "begin" lines */
- if (left(HEADER.ctr_HeaderLine, 1) = 'M') then do
- MCOUNTER = MCOUNTER + 1
- end
-
- ctr_HeaderLine = ctr_HeaderLine + 1 /* bump header line counter */
-
- /* stop if uuencoded data or end of file is reached (case-sensitive) */
- FIRSTWORD = left(instring, 5)
- if ((FIRSTWORD = 'BEGIN')|(FIRSTWORD = 'begin')|(MCOUNTER=5)|(eof('datafile'))) then do
- /* Read in one additional line - this is done to catch a possible
- subsequent line which contains the actual "begin 644 filename"
- field of a uuencoded message. */
- instring = readln('datafile') /* read extra line from file */
- HEADER.ctr_HeaderLine = instring /* copy line into header structure */
- HEADER.LINES = ctr_HeaderLine +1 /* make note of # lines in header (plus one additional line) */
- STOP = YES
- end
-
- if (DEBUG >= 5) then do
- say '*** ctr_HeaderLine='ctr_HeaderLine 'HEADER.SEARCH_MAX='HEADER.SEARCH_MAX
- end
-
- /* Stop if number of lines searched exceeds specified maximum */
- if (ctr_HeaderLine = HEADER.SEARCH_MAX) then do
- if (DEBUG >= 5) then do
- say '*** Stopping header information search - headerlines limit reached'
- end
- HEADER.LINES = ctr_HeaderLine + 1 /* make note of # lines in header (plus one additional line) */
- STOP = YES
- end
- end
-
-
- /************************************************************************
- CLOSE FILE
- ************************************************************************/
-
- result = close('datafile')
-
-
- /************************************************************************
- SHOW BACK THE CONTENTS OF THE HEADER STRUCTURE
- Used for testing purposes only
- ************************************************************************/
-
- if (DEBUG >= 9) then do
- ctr_HeaderLine = 1
- say '*** HEADER.LINES='HEADER.LINES
- do until (ctr_HeaderLine = HEADER.LINES)
- say ctr_HeaderLine' 'HEADER.ctr_HeaderLine
- ctr_HeaderLine = ctr_HeaderLine + 1
- end
- end
-
-
-
- /************************************************************************
- PROCESS HEADER
- Check to see if file's contents contain a valid UUCP message, and if so,
- what type, etc.
- ************************************************************************/
-
- if (DEBUG >= 5) then do
- say '*** process_header()'
- end
-
- result = PROCESS_HEADER()
- if (UUFILE.VALID = YES) then TOTALS.VALID = TOTALS.VALID + 1
-
-
-
- /************************************************************************
- CLEAR HEADER STRUCTURE
- Once the file has been dealt with, empty the header structure so data
- isn't accidentally applied to the next file
- ************************************************************************/
-
- if (DEBUG >= 6) then do
- say 'clearing header structure'
- end
- ctr_HeaderLine = 1
- do until (ctr_HeaderLine = HEADER.LINES)
- HEADER.ctr_HeaderLine = ' '
- ctr_HeaderLine = ctr_HeaderLine + 1
- end
-
-
-
- /***********************************************************************
- REMOVE INVALID CHARACTERS FROM ENTRY'S BINARY NAME
- ************************************************************************/
-
- /* Remove carriage return (ASCII decimal 13, hex '0x0D') */
- CR = x2c('0D')
- UUFILE.OUTNAME = compress(UUFILE.OUTNAME, CR)
-
-
-
- /************************************************************************
- DISPLAY INFORMATION ABOUT FILE AND MESSAGE
- ************************************************************************/
-
- if (QUIET = OFF) then do
- if (DEBUG >= 5) then do
- say '*** Header lines:' HEADER.LINES
- end
- say 'Source :' UUFILE.INNAME
- say 'Subject:' UUFILE.SUBJECT /* display message subject */
-
- if (UUFILE.VALID = YES) then do
- say 'Encoder:' UUFILE.UUENCODER
- say 'Part No:' UUFILE.PARTNUM 'of' UUFILE.PARTSTOTAL
- say 'Binary :' UUFILE.OUTNAME
- end
- else do
- say 'Note : File doesn''t contain valid/recognizable uuencoded data.'
- end
- say ''
- end
-
-
-
- /************************************************************************
- PUT FILE INFORMATION INTO TEMPORARY DATA FILE
- Do not add an entry to the data file if it is not a valid message
- ************************************************************************/
-
- if (UUFILE.VALID = YES) then do
- OUT_STRING = UUFILE.INNAME UUFILE.OUTNAME UUFILE.PARTNUM UUFILE.PARTSTOTAL
- result = open('TEMPDATA', TEMPDATAFILENAME, Append)
- writeln('TEMPDATA', OUT_STRING)
- result = close('TEMPDATA')
- end
-
- end
-
-
-
- /***************************************************************************
- DISPLAY TOTALS
- ***************************************************************************/
-
- if (QUIET = OFF) then do
- PERCENT = ((TOTALS.VALID/TOTALS.MSGS)*100)
- PERCENT = trunc(PERCENT, 2)
- say 'Total files examined :' TOTALS.MSGS
- say 'Valid uuencoded parts:' TOTALS.VALID '('PERCENT'%)'
- end
-
-
-
- /***************************************************************************
- SORT THE DATA ARRAY
- ***************************************************************************/
-
- ctr_init = 0 /* counter: initilization loop */
- ctr_infileline = 0 /* counter: current line of input file */
- LIST. = ' ' /* initialize data array */
- LIST.TOTALENTRIES = 0 /* total entries in array */
-
- if (QUIET = OFF) then do
- say ''
- say 'Phase: Sorting entries'
- say ''
- end
-
- /* Open temp data file for reading */
- result = open('TEMPDATA', TEMPDATAFILENAME, read)
-
- if (DEBUG >= 5) then do
- say '*** TOTALS.VALID='TOTALS.VALID '(# expected lines in file)'
- end
-
- /* Read through each line of temporary data file. Note: the number of lines
- in the file should be identical to the number of valid uuencoded messages
- which were found. */
-
- do ctr_infileline=1 to TOTALS.VALID
- /* read line from file */
- instring = readln('TEMPDATA')
-
- /* Disect line */
- PARTNAME = word(instring, 1) /* actual file containing binary part */
- BINARYNAME = word(instring, 2) /* name of eventual resulting binary */
- PARTNUM = word(instring, 3) /* number of current part */
- PARTSTOTAL = word(instring, 4) /* total number of parts to binary */
-
- if (DEBUG >= 5) then do
- say ''
- say '*** PARTNUM='PARTNUM 'PARTSTOTAL='PARTSTOTAL
- end
-
-
- /************************************************************************
- SAFETY CHECK FOR PART/TOTAL VALUES
- Force part number to 1 and part total to 1 if total parts is zero. This
- is done in case a file contains a binary which has no valid part numbers.
- Note: this will not effect messages which are part 0 of (x) parts; this
- only takes effect if the total number of parts is 0.
- ************************************************************************/
-
- if (PARTSTOTAL = 0) then do
- if (DEBUG >= 5) then do
- say '*** Forcing PARTNUM to 1, PARTSTOTAL to 1'
- end
- PARTNUM = 1
- PARTSTOTAL = 1
- end
-
-
- if (DEBUG >= 5) then do
- say '*** PARTNUM='PARTNUM 'PARTSTOTAL='PARTSTOTAL
- end
-
-
- /* reset variables before entering loop (mandatory - do not move) */
- STOP = NO /* loop */
- ctr_entry = 0 /* counts entries */
-
- /* Search through entry list to see if entry already exists for binary */
- do until (STOP = YES)
- if (DEBUG >= 5) then do
- say '*** ctr_infileline='ctr_infileline 'ctr_entry='ctr_entry 'LIST.TOTALENTRIES='LIST.TOTALENTRIES 'LIST.'ctr_entry'='LIST.ctr_entry
- end
-
- /* if an entry exists, add information to it */
- if (LIST.ctr_entry = BINARYNAME) then do
- if (DEBUG >= 5) then do
- say BINARYNAME 'entry already exists'
- end
- STOP = YES /* escape from the loop */
-
- /* Add part information to existing entry */
- LIST.ctr_entry.PARTNUM = PARTNAME /* copy part name into part entry */
- if (DEBUG >= 5) then do
- say '*** LIST.'ctr_entry'.'PARTNUM'=' LIST.ctr_entry.PARTNUM
- end
- end
-
- /* if no entry already exists, create one */
- if (ctr_entry = LIST.TOTALENTRIES) then do
- LIST.TOTALENTRIES = LIST.TOTALENTRIES + 1 /* bump entries counter */
- LIST.ctr_entry = BINARYNAME /* copy binary name into entry slot */
- STOP = YES /* stop scanning through entry list */
- if (DEBUG >= 5) then do
- say 'Created entry' ctr_entry 'for' BINARYNAME '(Total entries:' LIST.TOTALENTRIES')'
- end
-
- /* Initialize entry's part information (begin at one, go to last part) */
- do ctr_part=1 to PARTSTOTAL
- LIST.ctr_entry.ctr_part = '<undefined>'/* initilize the part entry */
- LIST.ctr_entry.PARTNUM = PARTNAME /* copy part name into part entry */
- LIST.ctr_entry.MAXPARTS= PARTSTOTAL /* make note of total number of parts for entry */
- if (DEBUG >= 5) then do
- say '*** LIST.'ctr_entry'.MAXPARTS=' LIST.ctr_entry.MAXPARTS
- say '*** LIST.'ctr_entry'.'ctr_part'=' LIST.ctr_entry.ctr_part
- end
- end
- end
- ctr_entry = ctr_entry +1 /* bump entry counter */
- end
-
-
- /* display output */
- if (QUIET = OFF) then do
- say BINARYNAME '(part' PARTNUM 'of' PARTSTOTAL') - filename:' PARTNAME
- end
- end
-
-
- /* Close temp data file for reading */
- if (DEBUG >= 6) then do
- say 'Closing:' TEMPDATAFILENAME
- end
- result = close('TEMPDATA')
- address command 'delete' TEMPDATAFILENAME 'quiet'
-
-
-
- /***************************************************************************
- REDISPLAY ENTIRE CONTENTS OF THE NOW-SORTED LIST
- ***************************************************************************/
-
- if (DEBUG >= 8) then do
- say ''
- say 'Current entries:'
- do ctr_testentry=0 to (LIST.TOTALENTRIES-1)
- say 'Binary:' LIST.ctr_testentry '(MAXPARTS='LIST.ctr_testentry.MAXPARTS')'
- do ctr_testpart = 1 to LIST.ctr_testentry.MAXPARTS
- say 'LIST.'ctr_testentry'.'ctr_testpart':' LIST.ctr_testentry.ctr_testpart
- end
- say ''
- end
- end
-
-
-
- /***************************************************************************
- CHECK FOR VALIDITY OF ENTRIES (DISQUALIFY INCOMPLETE ENTRIES)
- If an entry is missing any of its parts, then make note of it
- ***************************************************************************/
-
- ctr_entry = 0 /* counter: current entry */
- ctr_part = 0 /* counter: current part of entry */
-
- if (QUIET = OFF) then do
- say ''
- say 'Phase: Validating entries'
- end
-
- /* Scan through all entries in list */
- do ctr_entry=0 to (LIST.TOTALENTRIES-1)
- if (DEBUG >= 5) then do
- say 'Binary:' LIST.ctr_entry
- end
- LIST.ctr_entry.VALIDENTRY = YES /* by default, entries are valid until proven invalid */
-
- /* Scan through all parts of entry */
- if (DEBUG >= 5) then do
- say '*** MAXPARTS='LIST.ctr_entry.MAXPARTS
- end
- do ctr_part = 1 to LIST.ctr_entry.MAXPARTS
- if (DEBUG >= 5) then do
- say 'LIST.'ctr_entry'.'ctr_part':' LIST.ctr_entry.ctr_part
- end
-
- /* If part has not been defined, skip on to the next entry. This is
- done because if a single part is missing from the entry, then part
- of the binary is missing. */
- if (LIST.ctr_entry.ctr_part = '<undefined>') then do
- LIST.ctr_entry.VALIDENTRY = NO /* make entry invalid */
- if (DEBUG >= 5) then do
- say '*** Invalid entry'
- end
- end
- end
- if (LIST.ctr_entry.VALIDENTRY = NO) then do
- if (DEBUG >= 5) then do
- say 'Invalid entry - part missing'
- end
- end
- end
-
-
-
- /***************************************************************************
- JOIN VALID ENTRIES
- Now the validity of each entry has been determined, join together the parts
- of each valid entry into an AmigaDOS file
- ***************************************************************************/
-
- ctr_entry = 0 /* counter: current entry */
- ctr_part = 0 /* counter: current part of entry */
-
- if (QUIET = OFF) then do
- say ''
- say 'Phase: Joining valid entries'
- say ''
- end
-
-
-
- /***************************************************************************
- ADD ENTRY TO LOG IF VALID, IF EXISTS IN LOG FLAG ENTRY AS INVALID
- If an entry is valid and is not already in the log, add it to the log so it
- won't be processed in the future. If an entry is valid and IS in the log
- already, mark it as invalid so it will not be processed (joined/decoded).
- ***************************************************************************/
-
- /***
- If log exists, open it for reading (name is based upon newsgroup)
- read file line by line until eof reached
- get filename from line and assign to LOGDATA.<line_number>.LOG_FILENAME
- get add date from line and assign to LOGDATA.<line_number>.LOG_DATEADDED
- get add time from line and assign to LOGDATA.<line_number>.LOG_TIMEADDED
- end
- do ctr=1 to end of LIST structure (LIST will be compared to LOGDATA, not the other way around)
- compare LIST's binary name to LOGDATA.<line_number>.LOG_FILENAME
- if there's a match (entry was already processed), then LIST.ctr_entry.VALIDENTRY = NO
- if there's NOT a match (entry was not already processed, then change
- nothing (invalid entries will remain invalid)
- end
- end
- close log
-
- If log does't exist, create it by opening it for writing (name is based upon newsgroup name)
- scan through LIST struture entry by entry until end reached
- if entry is valid
- write binary name to line
- write date added to line
- end
- if entry is invalid
- do nothing
- end
- end of LIST structure reached
- close log
- ***/
-
- /***
- /* Initialize the LOGDATA array */
- LOGDATA. = ' '
- ctr_line = 0
-
- /* Generate name of log file (logfile name is based upon newsgroup name) */
- LOGNAME = LOGS''NEWSGROUP
- say '*** LOGNAME='LOGNAME
-
- /* If log exists, open it for reading */
- if (exists(LOGNAME)>0) then do
- say '***' LOGNAME 'exists, opening...'
- result = open('LOGFILE', LOGNAME, read) /* open log file */
- say '*** Reading log file'
- do until(eof(LOGNAME))
- instring = readln('LOGFILE') /* read line */
- LOGDATA.ctr_line.LOG_FILENAME = word(instring, 1) /* get filename */
- LOGDATA.ctr_line.LOG_DATEADDED = word(instring, 2) /* get date */
- LOGDATA.ctr_line.LOG_TIMEADDED = word(instring, 3) /* get time */
- ctr_line = ctr_line + 1 /* bump counter*/
- LOGDATA.ENTRIES = ctr_line /* tracks total entries in log structure */
- say '***' ctr_line LOGDATA.ctr_line.LOG_FILENAME LOGDATA.ctr_line.LOG_DATEADDED LOGDATA.ctr_line.LOG_TIMEADDED
- end
-
- /* compare LIST struct entries to LOGDATA entries */
- do ctr_list=1 to LIST.TOTALENTRIES /* go through current entry data */
- say '*** ctr_list='ctr_list
- do ctr_log=1 to LOGDATA.ENTRIES /* go through log data */
- /* Compare current list entry to name from log line */
- if (LIST.ctr_list = LOGDATA.ctr_log.LOG_FILENAME) then do
- LIST.ctr_list.VALIDENTRY = NO /* in log, so don't process again */
- end
- say '*** ctr_log='ctr_log 'LISTname='LIST.ctr_list 'LOG_FILENAME='LOGDATA.ctr_log.LOG_FILENAME
- end
- end
- say '*** Closing log'
- result = close('LOGFILE') /* close log */
- end
- ***/
-
-
- /* If log doesn't exist, create it by opening it for writing */
-
-
-
- /***************************************************************************
- GENERATE TEMPORARY DECODE SCRIPT NAME
- This data file is used to store information for the 'form binaries' phase
- ***************************************************************************/
-
- TEMP_DATE = space(date(julian), 0)
- TEMP_TIME = space(time(seconds), 0)
- DECODESCRIPT = 'decode_'TEMP_DATE''TEMP_TIME'.scr'
- if (DEBUG >= 1) then do
- say 'Decode script:' DECODESCRIPT
- end
-
- /* Create the decode script */
- result = open('DECODEFILE', DECODESCRIPT, write)
- writeln('DECODEFILE', 'cd' DEST_DIR)
- result = close('DECODEFILE')
-
-
- /* Rescan the entry list and join only valid uuencoded parts (all parts of
- a binary must be present for the joining to occur for that binary) */
-
- do ctr_entry=0 to (LIST.TOTALENTRIES-1)
- if (LIST.ctr_entry.VALIDENTRY = YES) then do
- PART_STRING = '' /* initialize string containing part names */
- if (DEBUG >= 5) then do
- say 'Binary:' LIST.ctr_entry
- end
-
- /* Create string containing entry names to be joined */
- do ctr_part = 1 to LIST.ctr_entry.MAXPARTS
- if (DEBUG >= 5) then do
- say 'LIST.'ctr_entry'.'ctr_part':' LIST.ctr_entry.ctr_part
- end
- PART_NAME = SOURCE_DIR''LIST.ctr_entry.ctr_part
- PART_STRING = PART_STRING' 'PART_NAME
- end
-
-
- /*********************************************************************
- ADD ENTRY TO DECODE SCRIPT
- The resulting script will be run late to decode all of the joined
- binaries
- *********************************************************************/
-
- messageline = 'echo "Decoding:' LIST.ctr_entry'"'
- joinline = 'join' PART_STRING 'TO' DEST_DIR''LIST.ctr_entry'.uu'
- outline = UUDECODER' 'DEST_DIR''LIST.ctr_entry'.uu'
- deleteline = 'delete' DEST_DIR''LIST.ctr_entry'.uu quiet'
- if (DEBUG >= 5) then do
- say outline
- end
- result = open('DECODEFILE', DECODESCRIPT, append)
- if (QUIET = OFF) then do
- writeln('DECODEFILE', messageline) /* displays message to Shell */
- end
- writeln('DECODEFILE', joinline) /* join parts */
- writeln('DECODEFILE', outline) /* decode joined file */
- writeln('DECODEFILE', deleteline) /* delete joined file, leaving binary behind */
- result = close('DECODEFILE') /* close file */
- TOTALS.DECODED = TOTALS.DECODED + 1 /* bump counter */
- end
- end
-
-
-
- /***************************************************************************
- FORM BINARIES PHASE
- ***************************************************************************/
-
- /* Execute the decode script */
- if (QUIET = OFF) then do
- say 'Phase: Decoding'
- say ''
- end
- address command 'execute' DECODESCRIPT
- address command 'delete' DECODESCRIPT 'quiet'
-
-
-
- /***************************************************************************
- DISPLAY TOTALS
- ***************************************************************************/
-
- if (QUIET = OFF) then do
- PERCENT = ((TOTALS.VALID/TOTALS.MSGS)*100)
- PERCENT = trunc(PERCENT, 2)
- say ''
- say 'Total files examined :' TOTALS.MSGS
- say 'Valid uuencoded parts:' TOTALS.VALID '('PERCENT'%)'
- say 'Total binaries formed:' TOTALS.DECODED
- end
-
- exit /* program */
-
-
-
-
-
-
-
-
-
- PROCESS_HEADER: procedure expose HEADER. UUFILE. TOTALS. DEBUG
-
- /***************************************************************************
- Local definitions
- ***************************************************************************/
-
- SUCCESS = 1
- FAILURE = 0
-
- YES = 1 /* test condition */
- NO = 0 /* test condition */
- LOOKFORNAME = YES /* continue looking for name of uuencoded binary */
-
-
-
- /***************************************************************************
- SCAN THROUGH HEADER FOR SUBJECT LINE
- ***************************************************************************/
-
- if (DEBUG >= 5) then do
- say '*** Subject part search'
- end
-
- do ctr_line = 1 to HEADER.LINES
- if (upper(word(HEADER.ctr_line, 1)) = "SUBJECT:") then do
-
- /* Ensure message is not a reply */
- if (upper(word(HEADER.ctr_line, 2)) ~= "RE:") then do
- UUFILE.SUBJECT = subword(HEADER.ctr_line, 2)
-
- /******************************************************************
- SEARCH FOR BINARY NAME
- Search for default filename in Subject line - this is not a test
- condition (other tests may look for filenames; in such cases,
- the results of those tests are used
- ******************************************************************/
-
- EXTENSION.NUM= 29
- EXTENSION.1 = '.anim' /* ANIM (animation) */
- EXTENSION.2 = '.anm' /* ANIM (animation) */
- EXTENSION.3 = '.arc' /* ARC (archive) */
- EXTENSION.4 = '.arj' /* ARJ (archive) */
- EXTENSION.5 = '.avi' /* AVI (animation) */
- EXTENSION.6 = '.com' /* COM (executable; MS-DOS) */
- EXTENSION.7 = '.dl' /* DL (animation) */
- EXTENSION.8 = '.dms' /* DMS (archive; DiskMasher disk archiver, Amiga */
- EXTENSION.9 = '.exe' /* EXE (executable; MS-DOS) */
- EXTENSION.10 = '.g' /* GIF (image) */
- EXTENSION.11 = '.gif' /* GIF (image) */
- EXTENSION.12 = '.gl' /* GL (animation; Grasp) */
- EXTENSION.13 = '.ham' /* HAM (image; Hold And Modify image)*/
- EXTENSION.14 = '.iff' /* IFF (image or sound; Interchange File Format) */
- EXTENSION.15 = '.j' /* JPEG (image) */
- EXTENSION.16 = '.jpeg' /* JPEG (image) */
- EXTENSION.17 = '.jpg' /* JPEG (image) */
- EXTENSION.18 = '.lha' /* LHA (archive) */
- EXTENSION.19 = '.lzh' /* LZH (archive) */
- EXTENSION.20 = '.mpeg' /* MPEG (animation) */
- EXTENSION.21 = '.mpg' /* MPEG (animation) */
- EXTENSION.22 = '.run' /* RUN (archive; self-extracting LZH/LHA) */
- EXTENSION.23 = '.sda' /* SEA (archive; Self-Dissolving Archive) */
- EXTENSION.24 = '.sea' /* SEA (archive; Self-Extracting Archive) */
- EXTENSION.25 = '.tar' /* TAR (archive; Unix Tar) */
- EXTENSION.26 = '.z' /* Z (archive; Unix compress) */
- EXTENSION.27 = '.zip' /* ZIP (archive) */
- EXTENSION.28 = '.zoo' /* ZOO (archive) */
- EXTENSION.29 = '.zom' /* ZOM (archive; Zoom disk archiver, Amiga) */
-
-
- /* get number of words in the subject line */
- NUM_SUBJWORDS = words(UUFILE.SUBJECT)
-
- /* check each word of the subject line until all are checked */
- do ctr_word = 1 to NUM_SUBJWORDS
- TEMP_WORD = word(UUFILE.SUBJECT, ctr_word)
-
- /* check to see if possible extensions match any part of word */
- do ctr_extension = 1 to EXTENSION.NUM
- /* if there's a match, we've found the filename */
- if (pos(EXTENSION.ctr_extension, TEMP_WORD)>0) then do
- if (DEBUG >= 5) then do
- say '*** found filename in subject'
- end
- UUFILE.OUTNAME = TEMP_WORD /* set name */
- /*LOOKFORNAME = NO*/ /* stop looking for name */
- leave ctr_word /* escape from the loop */
- end
- end
- end
-
-
-
- /******************************************************************
- GENERIC PART NUMBER SEARCH
- Search for part numbers in Subject line for use with filename -
- this is not a test condition
- ******************************************************************/
-
- if (upper(word(HEADER.ctr_line, 1)) = "SUBJECT:") then do
- /* zero variables used to find part number and totals */
- LEFT = 0
- CENTER = 0
- RIGHT = 0
- CONTINUE = YES
-
-
-
- /***************************************************************
- GENERIC PART NUMBER SEARCH
- Check for part pattern: "[1/2]"
- ***************************************************************/
-
- if (CONTINUE=YES) then do
- if (DEBUG >= 5) then do
- say '*** [] search'
- end
- if (verify('[/]', HEADER.ctr_line)=0) then do
- LEFT = pos('[', HEADER.ctr_line)
- CENTER= pos('/', HEADER.ctr_line)
- RIGHT = pos(']', HEADER.ctr_line)
- /* Make sure the pattern components found are part number,
- not just erratic characters found in the Subject line */
- if (LEFT<CENTER)&(RIGHT>CENTER) then do
- UUFILE.PARTNUM = substr(HEADER.ctr_line, LEFT+1, (CENTER-LEFT-1))
- UUFILE.PARTSTOTAL = substr(HEADER.ctr_line, CENTER+1, (RIGHT-CENTER-1))
- CONTINUE=NO /* don't keep searching */
- end
- end
- end
-
-
-
- /***************************************************************
- GENERIC PART NUMBER SEARCH
- Check for part pattern: "(1/2)"
- ***************************************************************/
-
- if (CONTINUE=YES) then do
- if (DEBUG >= 5) then do
- say '*** () search'
- end
- if (verify('(/)', HEADER.ctr_line)=0) then do
- if (find(HEADER.ctr_line, '(part ')=0) then do /* make sure this is NOT a '(part 1/2)' pattern */
- LEFT = pos('(', HEADER.ctr_line)
- CENTER= pos('/', HEADER.ctr_line)
- RIGHT = pos(')', HEADER.ctr_line)
- /* Make sure the pattern components found are part number,
- not just erratic characters found in the Subject line */
- if (LEFT<CENTER)&(RIGHT>CENTER) then do
- UUFILE.PARTNUM = substr(HEADER.ctr_line, LEFT+1, (CENTER-LEFT-1))
- UUFILE.PARTSTOTAL = substr(HEADER.ctr_line, CENTER+1, (RIGHT-CENTER-1))
- CONTINUE=NO /* don't keep searching */
- end
- end
- end
- end
-
-
-
- /***************************************************************
- GENERIC PART NUMBER SEARCH
- Check for part pattern: "(part 1/2)"
- ***************************************************************/
-
- if (CONTINUE=YES) then do
- if (DEBUG >= 5) then do
- say '*** (part x/y) search'
- end
- if (verify('(/)', HEADER.ctr_line)=0) then do
- if (find(upper(HEADER.ctr_line), '(PART ')>0) then do /* check for the '(part' phrase */
- LEFT = (pos('(', HEADER.ctr_line)+5) /* LEFT begins AFTER the 'part ' keyword */
- CENTER= pos('/', HEADER.ctr_line)
- RIGHT = pos(')', HEADER.ctr_line)
- /* Make sure the pattern components found are part number,
- not just erratic characters found in the Subject line */
- if (LEFT<CENTER)&(RIGHT>CENTER) then do
- /* Get part number - strip any leading zeros */
- UUFILE.PARTNUM = substr(HEADER.ctr_line, LEFT+1, (CENTER-LEFT-1))
- UUFILE.PARTNUM = strip(UUFILE.PARTNUM, leading, '0')
- /* Get total parts - strip any leading zeros */
- UUFILE.PARTSTOTAL = substr(HEADER.ctr_line, CENTER+1, (RIGHT-CENTER-1))
- UUFILE.PARTSTOTAL = strip(UUFILE.PARTSTOTAL, leading, '0')
- CONTINUE=NO /* don't keep searching */
- end
- end
- end
- end
-
-
-
- /***************************************************************
- GENERIC PART NUMBER SEARCH
- Check for part pattern: "{1/2}"
- ***************************************************************/
-
- if (CONTINUE=YES) then do
- if (DEBUG >= 5) then do
- say '*** {} search'
- end
- if (verify('{/}', HEADER.ctr_line)=0) then do
- LEFT = pos('{', HEADER.ctr_line)
- CENTER= pos('/', HEADER.ctr_line)
- RIGHT = pos('}', HEADER.ctr_line)
- /* Make sure the pattern components found are part number,
- not just erratic characters found in the Subject line */
- if (LEFT<CENTER)&(RIGHT>CENTER) then do
- UUFILE.PARTNUM = substr(HEADER.ctr_line, LEFT+1, (CENTER-LEFT-1))
- UUFILE.PARTSTOTAL = substr(HEADER.ctr_line, CENTER+1, (RIGHT-CENTER-1))
- CONTINUE=NO /* don't keep searching */
- end
- end
- end
-
-
-
- /***************************************************************
- GENERIC PART NUMBER SEARCH
- Check for part pattern: "part 1/2" (case-insensitive)
- ***************************************************************/
-
- if (CONTINUE = YES) then do
- if (DEBUG >= 5) then do
- say '*** part 1/2 search'
- end
- /* First check for the word "part" */
- LOC_PART = find(HEADER.ctr_line, 'part')
- if (LOC_PART > 0) then do
- /* When found, get the following word (hopefully x/y information */
- WORD_PART = word(HEADER.ctr_line, LOC_PART+1)
- /* Check to make sure x/y word contains a slash, denoting part information */
- if (verify('/', WORD_PART)=0) then do
- /* Slash was found - extract the part information */
- CENTER = pos('/', WORD_PART)
- UUFILE.PARTNUM = substr(WORD_PART, 1, CENTER-1)
- UUFILE.PARTSTOTAL = substr(WORD_PART, CENTER+1)
- CONTINUE=NO /* don't keep searching */
- end
- end
- end
-
-
-
- /***************************************************************
- GENERIC PART NUMBER SEARCH
- Check for part pattern: "1/2" (case-insensitive, no "part")
- ***************************************************************/
-
- if (CONTINUE = YES) then do
- if (DEBUG >= 5) then do
- say '*** 1/2 (no part) search'
- end
- LOOPAGAIN = YES
- ctr_word = 1
- /* Find number of words in Subject line */
- NUM_WORDS = words(HEADER.ctr_line)
-
- do until ((ctr_word > NUM_WORDS)|(LOOPAGAIN=NO))
- /* Look for a slash in the word being examined */
- WORD_PART = word(HEADER.ctr_line, ctr_word)
-
- if (verify('/', WORD_PART)=0) then do
- /* Slash was found - extract the part information */
- CENTER = pos('/', WORD_PART)
- TMP_PARTNUM = substr(WORD_PART, 1, CENTER-1)
- TMP_PARTSTOTAL = substr(WORD_PART, CENTER+1)
-
- /* only do this if PARTNUM and PARTSTOTAL are numbers */
- if ((datatype(TMP_PARTNUM, numeric)=1)&(datatype(TMP_PARTSTOTAL, numeric)=1)) then do
- UUFILE.PARTNUM = TMP_PARTNUM
- UUFILE.PARTSTOTAL = TMP_PARTSTOTAL
- LOOPAGAIN = NO /* stop the loop */
- CONTINUE = NO /* don't keep searching */
- end
- end
- ctr_word = ctr_word + 1
- end
- end
-
-
-
- /***************************************************************
- GENERIC PART NUMBER SEARCH
- Check for part pattern: "1 of 2"
- ***************************************************************/
-
- /* not implemented */
-
-
-
- /***************************************************************
- GENERIC PART NUMBER SEARCH
- Check for part pattern: "1of2"
- ***************************************************************/
-
- /* not implemented */
-
- end
- end
- end
- end
-
-
-
- /***************************************************************************
- SCAN THROUGH HEADER FOR POST-BIN INFORMATION
- Post-Bin uuencoded messages are recognized by the following characteristics:
- - The "pfile=" field bearing the file name (case sensitive)
- - The "part=" field bearing the part name (case sensitive)
- - The phrase "post-bin" must appear in the message (case sensitive)
- ***************************************************************************/
-
- /* Test condition flags: all must be true before assuming file contains a
- uuencoded message created using Post-Bin */
-
- TESTCOND_BEGIN = FALSE
- TESTCOND_PFILE = FALSE
- TESTCOND_PART = FALSE
- TESTCOND_POSTBIN = FALSE
-
- /* Scan through the header checking test conditions */
- if (DEBUG >= 5) then do
- say '*** Post-Bin search'
- end
-
- do ctr_line = 1 to HEADER.LINES
- /* Search for file name (PFILE test condition) */
- if (left(HEADER.ctr_line, 6) = 'pfile=') then do
- UUFILE.OUTNAME = substr(HEADER.ctr_line, 7, length(HEADER.ctr_line))
- UUFILE.OUTNAME = space(UUFILE.OUTNAME, 0)
- TESTCOND_PFILE = TRUE
- end
-
- /* Search for part number (PART test condition) */
- if (left(HEADER.ctr_line, 5) = 'part=') then do
- TESTCOND_PART = TRUE
- UUFILE.PARTNUM = substr(HEADER.ctr_line, 6, length(HEADER.ctr_line))
- UUFILE.PARTNUM = space(UUFILE.PARTNUM,0)
- end
-
- /* Search for "post-bin" phrase (POSTBIN test condition) */
- if (pos('post-bin', HEADER.ctr_line)>0) then do
- TESTCOND_POSTBIN = TRUE
- end
-
- /* If all test conditions are met, assume message contains a uuencoded
- message created using Post-Bin */
- if ((TESTCOND_PFILE = TRUE)&(TESTCOND_PART = TRUE)&(TESTCOND_POSTBIN = TRUE)) then do
- UUFILE.UUENCODER = 'Post-Bin'
- UUFILE.VALID = YES
- return SUCCESS
- end
- end
-
-
-
- /***************************************************************************
- SCAN THROUGH HEADER FOR UBIN-PC INFORMATION
- UBIN-PC uuencoded messages are recognized by the following characteristics:
- - The "BEGIN--cut here--CUT HERE--" sequence just before uuencoded data
- - The phrase "UBIN-PC" might appear in the message (case sensitive, not
- a requirement for the message to be uuencoded by UBIN-PC)
-
- The file name of a UBIN-PC encoded message is extracted from the Subject
- line, since there is no field name specifying it, nor do all parts of the
- encoded message contain references to the name other than in the Subject
- line. For this reason, the code used to extract names from Generic uuencoded
- messages is relied upon.
- ***************************************************************************/
-
- /* Test condition flags: all must be true before assuming file contains a
- uuencoded message created using UBIN-PC */
-
- TESTCOND_BEGINCUT = FALSE
- TESTCOND_UBINPC = FALSE
-
- /* Scan through the header checking test conditions */
- if (DEBUG >= 5) then do
- say '*** UBIN-PC search'
- end
-
- do ctr_line = 1 to HEADER.LINES
-
- /* Search for "begin-cut here" sequence (BEGINCUT test condition) */
- if (pos('BEGIN--cut here--CUT HERE--',HEADER.ctr_line)>0) then do
- TESTCOND_BEGINCUT = TRUE
- end
-
- /* Search for "UBIN-PC" phrase (UBINPC test condition) */
- if (pos('UBIN-PC', HEADER.ctr_line)>0) then do
- TESTCOND_UBINPC = TRUE
- end
-
- /* If all test conditions are met, assume message contains a uuencoded
- message created using UBIN-PC */
- if ((TESTCOND_BEGINCUT = TRUE)&&(TESTCOND_UBINPC = TRUE)) then do
- UUFILE.UUENCODER = 'UBIN-PC'
- UUFILE.VALID = YES
- return SUCCESS
- end
- end
-
-
-
- /***************************************************************************
- SCAN THROUGH HEADER FOR UUXFER INFORMATION
- UUXFER uuencoded messages are recognized by the following characteristics:
- - The "BEGIN----------------------Cut Here--------------------------"
- sequence just before uuencoded data
- - The phrase "UUXFER" might appear in the message (case sensitive, not
- a requirement for the message to be uuencoded by UUXFER)
-
- Names are extracted from a line found in the header (contains "UUXFER"
- string). Part numbers are extracted from the Subject line.
- ***************************************************************************/
-
- /* Test condition flags: all must be true before assuming file contains a
- uuencoded message created using UUXFER */
-
- TESTCOND_BEGINCUT = FALSE
- TESTCOND_UUXFER = FALSE
-
- /* Scan through the header checking test conditions */
- if (DEBUG >= 5) then do
- say '*** UUXFER search'
- end
- do ctr_line = 1 to HEADER.LINES
-
- /* Search for "begin-cut here" sequence (BEGINCUT test condition) */
- if (pos('BEGIN----------------------Cut Here--------------------------',HEADER.ctr_line)>0) then do
- TESTCOND_BEGINCUT = TRUE
- end
-
- /* Search for "UUXFER" phrase (UUXFER test condition) */
- if (pos('UUXFER', HEADER.ctr_line)>0) then do
- /* find the name and part on this line */
- UUFILE.OUTNAME = word(HEADER.ctr_line, 1)
- UUFILE.OUTNAME = space(UUFILE.OUTNAME, 0)
- TESTCOND_UUXFER = TRUE
- end
-
- /* If all test conditions are met, assume message contains a uuencoded
- message created using UUXFER */
- if ((TESTCOND_BEGINCUT = TRUE)&&(TESTCOND_UUXFER = TRUE)) then do
- UUFILE.UUENCODER = 'UUXFER'
- UUFILE.VALID = YES
- return SUCCESS
- end
- end
-
-
-
- /***************************************************************************
- SCAN THROUGH HEADER FOR "UUENCODE (R.E.M.)" INFORMATION
- UUENCODE uuencoded messages are recognized by the following characteristics:
- - The "section (x) of uuencode" sequence just before uuencoded data
- (case sensitive)
- - The phrase "by R.E.M." (case sensitive)
- ***************************************************************************/
-
- /* Test condition flags: all must be true before assuming file contains a
- uuencoded message created using "UUENCODE (R.E.M.)" */
-
- TESTCOND_SECTIONOF = FALSE
- TESTCOND_BYREM = FALSE
-
- /* Scan through the header checking test conditions */
- if (DEBUG >= 5) then do
- say '*** REM search'
- end
-
- do ctr_line = 1 to HEADER.LINES
- /* Search for "section (x) of uuencode" sequence (SECTIONOF test condition) */
- if (pos('section',HEADER.ctr_line)>0) then do
- if (pos('of uuencode', HEADER.ctr_line)>0) then do
- /* File name is stored on same line after "of file"- extract it */
- REM_NAMELOC = find(HEADER.ctr_line, 'of file')
- UUFILE.OUTNAME = word(HEADER.ctr_line, REM_NAMELOC+2)
- UUFILE.OUTNAME = space(UUFILE.OUTNAME, 0)
- TESTCOND_SECTIONOF = TRUE
- end
- end
-
- /* Search for "section (x) of uuencode" sequence (SECTIONOF test condition) */
- if (pos('by R.E.M.',HEADER.ctr_line)>0) then do
- TESTCOND_BYREM = TRUE
- end
-
- /* If all test conditions are met, assume message contains a uuencoded
- message created using UBIN-PC */
- if ((TESTCOND_SECTIONOF = TRUE)&(TESTCOND_BYREM = TRUE)) then do
- UUFILE.UUENCODER = 'uuencode (R.E.M.)'
- UUFILE.VALID = YES
- return SUCCESS
- end
- end
-
-
-
- /***************************************************************************
- SCAN THROUGH HEADER FOR GENERIC UUENCODED INFORMATION
- Generic uuencoded messages are recognized by the following characteristics:
- - The "BEGIN --- CUT HERE --- Cut Here --- cut here ---" sequence just
- before uuencoded data
- ***************************************************************************/
-
- /* Test condition flags: at least one must be true before assuming file
- contains a generic uuencoded message */
-
- TESTCOND_BEGINCUT1 = FALSE
- TESTCOND_BEGINCUT2 = FALSE
- TESTCOND_BEGINCUT3 = FALSE
- TESTCOND_BEGINNUMNAME= FALSE
- TESTCOND_CUTHERE = FALSE
- TESTCOND_PART1 = FALSE
-
-
- /* Scan through the header checking test conditions */
- if (DEBUG >= 5) then do
- say '*** Generic search'
- end
-
-
-
- do ctr_line = 1 to HEADER.LINES
-
- /* Search for "begin <number> <filename>" - primary method (case
- sensitive. */
-
- if (LOOKFORNAME = YES) then do
- if (pos('begin', HEADER.ctr_line)>0) then do
- if (DEBUG >= 5) then do
- say '*** begin line found'
- end
- /* Check to ensure second word is a number; if yes, continue */
- if (datatype(word(HEADER.ctr_line, 2), Numeric)>0) then do
- if (DEBUG >= 5) then do
- say '*** 2nd word is number'
- end
- /* Extract name from third word */
- UUFILE.OUTNAME = word(HEADER.ctr_line, 3) /* get name */
- UUFILE.OUTNAME = space(UUFILE.OUTNAME, 0) /* strip spaces */
- TESTCOND_BEGINNUMNAME = TRUE /* test condition met */
- LOOKFORNAME = NO /* stop looking for name */
-
- /* temp */
- UUFILE.UUENCODER = 'Generic'
- UUFILE.VALID = YES
- return SUCCESS
- end
- end
- end
-
-
- /* Search for "begin-cut here" sequence (BEGINCUT1 test condition) */
- /* Filename does not have to be found for message with this "begin"
- line to be valid */
-
- if (pos('BEGIN --- CUT HERE --- Cut Here --- cut here ---',HEADER.ctr_line)>0) then do
- if (DEBUG >= 5) then do
- say '*** found begin/cut'
- end
- TESTCOND_BEGINCUT1 = TRUE
-
- /* extract name from this line */
- if (LOOKFORNAME = YES) then do
- if (DEBUG >= 5) then do
- say '*** looking for name'
- end
-
- /* word 12 should contain name - if it does, extract it, otherwise
- keep looking (this is for cases where a message may have the
- valid "begin-cut here" sequence, but the binary name may be
- stored elsewhere, such as on a "begin 664 filename" line */
-
- if (words(HEADER.ctr_line)>=12) then do
- if (DEBUG >= 5) then do
- say '*** found 12th word'
- end
- UUFILE.OUTNAME = word(HEADER.ctr_line, 12) /* 12th word is name */
- UUFILE.OUTNAME = space(UUFILE.OUTNAME, 0) /* strip spaces from name */
- LOOKFORNAME = NO /* stop looking for name */
-
- end
- end
- /* temp */
- UUFILE.UUENCODER = 'Generic'
- UUFILE.VALID = YES
- return SUCCESS
- end
-
-
- /* Search for "BEGIN------------" sequence (BEGINCUT2 test condition) */
- if (pos('BEGIN------------',HEADER.ctr_line)>0) then do
- TESTCOND_BEGINCUT2 = TRUE
- /* extract name from this line */
- if (LOOKFORNAME = YES) then do
- UUFILE.OUTNAME = word(HEADER.ctr_line, 2) /* 2nd word is name */
- UUFILE.OUTNAME = space(UUFILE.OUTNAME, 0) /* strip spaces from name */
- LOOKFORNAME = NO /* stop looking for name */
-
- /* temp */
- UUFILE.UUENCODER = 'Generic'
- UUFILE.VALID = YES
- return SUCCESS
- end
- end
-
-
- /* Search for "BEGIN -- CUT HERE -- cut here -- " sequence (BEGINCUT3
- test condition */
- if (pos('BEGIN -- CUT HERE -- cut here -- ',HEADER.ctr_line)>0) then do
- TESTCOND_BEGINCUT3 = TRUE
- /* extract name from this line */
- if (LOOKFORNAME = YES) then do
- UUFILE.OUTNAME = word(HEADER.ctr_line, 9) /* 9th word is name */
- UUFILE.OUTNAME = space(UUFILE.OUTNAME, 0) /* strip spaces from name */
- LOOKFORNAME = NO
-
- /* temp */
- UUFILE.UUENCODER = 'Generic'
- UUFILE.VALID = YES
- return SUCCESS
- end
- end
-
-
- /* Search for "------------ Part" sequence (PART1 test condition) */
- if (pos('------------ Part',HEADER.ctr_line)>0) then do
- if (DEBUG >= 5) then do
- say '*** part found (TESTCOND_PART1)'
- end
- /* name cannot be extracted from this line - must rely on generic
- search methods (ie: "Subject" or "begin" lines) */
- TESTCOND_PART1 = TRUE
-
- /* temp */
- UUFILE.UUENCODER = 'Generic'
- UUFILE.VALID = YES
- return SUCCESS
- end
-
-
- /* Search for "CUT HERE" sequence (CUTHERE test condition) */
- if (pos('------------------------- CUT HERE --------------------------',HEADER.ctr_line)>0) then do
- if (DEBUG >= 5) then do
- say '*** CUT HERE found (TESTCOND_CUTHERE)'
- end
- /* name cannot be extracted from this line - must rely on generic
- search methods (ie: "Subject" or "begin" lines) */
- TESTCOND_CUTHERE = TRUE
-
- /* temp */
- UUFILE.UUENCODER = 'Generic'
- UUFILE.VALID = YES
- return SUCCESS
- end
- end
-
-
- return SUCCESS
-